<?php
/**
 * 国内发货需求文件,上传
 * User: bgl
 * Date: 2022/11/3
 * Time: 17:36
 */

namespace App\Admin\Controllers\Delivery;

use App\Func\UploadFile;
use App\Importer\Basics\BImporter;
use App\Models\Basics\SysArea;
use App\Models\Basics\SysPlat;
use App\Models\Basics\SysPlatAccount;
use App\Models\Basics\SysCountry;
use App\Models\Delivery\DeliveryReview;
use App\Models\Inventory\InventoryCn;
use App\Models\Product\ProductAmazonSku;
use App\Models\Product\ProductRakutenSku;
use App\Models\Product\ProductSku;
use App\Util\RExcel;
use Encore\Admin\Facades\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Encore\Admin\Controllers\AdminController;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class DeliveryReviewUploadController extends AdminController {

    protected $title = 'CN-发货需求文件上传';

    protected function grid()
    {
        return view("delivery.delivery-review.index");
    }

    public function upload(Request $request){

        $type = $request->get('type');
        if(!$type) return response()->json(['status' => false, 'message' => '类型不能为空！']);

        $platId = $request->get('plat_id');
        if(!$platId) return response()->json(['status' => false, 'message' => '平台不能为空！']);

        $file = $request->file('source_file');
        if(!$file) return response()->json(['status' => false, 'message' => '文件不能为空！']);

        if ($file->isValid()) {
            if($type == DeliveryReview::TYPE_WAREHOUSE){
                $isFnsku = $request->get('is_fnsku');
                if(!$isFnsku) return response()->json(['status' => false, 'message' => '海外仓是否标贴不能为空！']);
                $res = $this->{'_import'.$type}($file,$platId,$isFnsku);
            }else{
                $res = $this->{'_import'.$type}($file,$platId);
            }
            if(is_array($res)) {
                if($res['flag']){
                    admin_toastr('文件：'.$res['data'].' 上传成功！');
                }else{
                    admin_toastr($res['data'],'error');
                }
            }else{
                return $res;
            }
        }else{
            admin_toastr('无效文件！','error');
        }
        return back()->withInput();
    }

    /**
     * FBA文件上传
     * @param UploadedFile $file
     * @param $platId
     * @return array|\Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    private function _import1(UploadedFile $file, $platId){
        try{

            $data = Excel::toArray(new BImporter(),$file);
            $data = $data[0];
            if(!$data) return ['flag' => false,'data' => '请上传包含有数据的文件！'];
            $errors = [];
            $count = 1;
            $arr = [];
            $type = DeliveryReview::TYPE_FBA; //FBA
            $items = [];

            $fileName = $file->getClientOriginalName();
            $reviewCount = DeliveryReview::query()->where('type',$type)->where('file_name',$fileName)->count();
            if($reviewCount) return ['flag' => false,'data' => '发货需求文件已存在！'];

            foreach($data as $row){
                $count++;
                $_country = $row[0] ? trim($row[0]) : '';
                $sku = $row[1] ? trim($row[1]) : '';
                $platSku = $row[2] ? trim($row[2]) : '';
                $asin = $row[3] ? trim($row[3]) : '';
                $tag = $row[4] ? trim($row[4]) : '';
                $skuName = $row[5] ? trim($row[5]) : '';
                $skuModelNo = $row[6] ? trim($row[6]) : '';
                $number = $row[7] ? trim($row[7]) : 0;
                $account = $row[8] ? trim($row[8]) : '';
                $channel = $row[9] ? trim($row[9]) : '';
                $remark = $row[10] ? trim($row[10]) : '';

                if (count($row) <= 10) {
                    $errors[$count] = '模板格式异常，请查看模板是否符合上传要求！';
                    continue;
                }
                if(!$_country || !$sku || !$platSku || !$asin || !$skuName){
                    $errors[$count] = '必填项不能为空';
                    continue;
                }

                $country = strtoupper($_country);
                $countryId = SysCountry::getIdByCountry($country);
                if(!$countryId){
                    $errors[$count] = $_country.'系统不存在该国家';
                    continue;
                }

                $key = $country.'-'.$platSku;
                if(!in_array($key, $arr)){
                    $arr[$count] = $key;
                }else{
                    $errors[$count] = '重复记录';
                    continue;
                }

                $productSku = ProductSku::getModelByCode($sku);
                if(!$productSku){
                    $errors[$count] = $sku.'系统不存在该sku';
                    continue;
                }

                //亚马逊产品
                $amazonSku = ProductAmazonSku::query()
                    ->where('country_id', $countryId)
                    ->where('seller_sku', $platSku)
                    ->first();
                if(!$amazonSku){
                    $errors[$count] = $key.'系统未匹配到该国家下的亚马逊SKU';
                    continue;
                }
                if($amazonSku->psku_id != $productSku->id){
                    $errors[$count] = $key.',对应产品SKU不匹配 (请核对产品SKU是否正确？1)';
                    continue;
                }
                if ($amazonSku->account->aws_region == 'EU') { //EU，验证产品型号字段
                    if ($productSku->classify->model_no != $skuModelNo) {
                        $errors[$count] = $key.',对应产品SKU产品型号不匹配 (请核对产品SKU产品型号标是否正确？)';
                        continue;
                    }
                }

                $strPskuCn  = formatTrim(' ', '', $productSku->psku_cn); //去除产品sku中的所有空格
                $strSkuName = formatTrim(' ', '', $skuName); //去除excel产品中的所有空格
                if($strPskuCn != $strSkuName){
                    $errors[$count] = $key.',对应产品名称不匹配 (请核对产品名称是否正确？2)';
                    continue;
                }

                if($amazonSku->child_asin != $asin){
                    $errors[$count] = $key.',对应ASIN不匹配 (请核对ASIN是否正确？)';
                    continue;
                }

                /******** 验证库存(参数) ************/
                $areaId = SysCountry::getAreaIdByCountryId($countryId);
                if(!$areaId){
                    $errors[$count] = $_country.'系统不存在该站点';
                    continue;
                }
                $items[$key] = [
                    'plat_id' => $platId,
                    'area_id' => $areaId,
                    'psku_id' => $productSku->id,
                    'apply_num' => $number,
                ];
                /********* 验证库存(参数) ***********/
            }

            if(empty($items)){
                $errors[] = '本次上传文件未能导入系统：无符合条件的数据';
            }

            /********* 验证库存 start***********/
            $applyTotalArr = getArrayValueSum($items);
            $inventoryErrors = [];
            foreach ($items as $_key => $_detail){
                $inventory = InventoryCn::query()
                    ->where('area_id',$_detail['area_id'])
                    ->where('psku_id',$_detail['psku_id'])
                    ->first();
                if (!$inventory) {
                    $inventoryErrors[$_key] = '无站点库存';
                    continue;
                }

                //验证：库存总量是否满足
                $skuApplyTotal = $applyTotalArr[$_detail['psku_id']]; //同一sku的累计总量
                if ($inventory->instant < $skuApplyTotal) {
                    $inventoryErrors[$_key] = '站点库存总量小于发货总数量，当前库存:'.$inventory->instant.',SKU总申发数量为:'.$skuApplyTotal;
                }

                //验证：库存是否满足
                if ($inventory->instant < $_detail['apply_num']) {
                    $inventoryErrors[$_key] = '站点库存不足，差额：'.($_detail['apply_num'] - $inventory->instant);
                    continue;
                }
            }
            if(!empty($inventoryErrors)){
                return RExcel::importResult($inventoryErrors);
            }
            /********* 验证库存 end***********/

            if(empty($errors)){
                DB::beginTransaction();
                //创建信息
                $reviewObj = DeliveryReview::query()
                    ->create([
                        'plat_id'   => $platId,
                        'type'      => $type,
                        'file_name' => $fileName,
                        'seller_id' => Admin::user()->id
                    ]);
                if($reviewObj){
                    //上传文件
                    $fileDir = DeliveryReview::fileDir($type, strtotime($reviewObj->created_at));
                    if(!is_dir($fileDir)){
                        mkdir($fileDir,0777,true);
                        chmod($fileDir, 0777);
                    }
                    $uploadFile = UploadFile::getInit();
                    $uploadFile->upload($file, $fileDir);
                    DB::commit();
                }else{
                    DB::rollBack();
                }

                return ['flag' => true,'data' => $fileName];
            }else{

               return RExcel::importResult($errors);
           }
       }catch(\Exception $e){
           DB::rollBack();
           report($e);
           return ['flag' => false,'data' => '系统异常！'];
       }
   }

    /**
     * 海外仓文件上传
     * @param UploadedFile $file
     * @param $platId
     * @param $isFnsku
     * @return array|\Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    private function _import2(UploadedFile $file,$platId,$isFnsku){
        try{

            $data = Excel::toArray(new BImporter(),$file);
            $data = $data[0];
            if(!$data) return ['flag' => false,'data' => '请上传包含有数据的文件！'];
            $errors = [];
            $count = 1;
            $arr = [];
            $type = DeliveryReview::TYPE_WAREHOUSE; //海外仓
            $items = [];

            $fileName = $file->getClientOriginalName();
            $reviewCount = DeliveryReview::query()->where('type',$type)->where('file_name',$fileName)->count();
            if($reviewCount) return ['flag' => false,'data' => '发货需求文件已存在！'];

            foreach($data as $row){
                $count++;
                $_country = $row[0] ? trim($row[0]) : '';
                $sku = $row[1] ? trim($row[1]) : '';
                $platSku = $row[2] ? trim($row[2]) : '';
                $asin = $row[3] ? trim($row[3]) : '';
                $tag = $row[4] ? trim($row[4]) : '';
                $skuName = $row[5] ? trim($row[5]) : '';
                $skuModelNo = $row[6] ? trim($row[6]) : '';

                $number = $row[7] ? trim($row[7]) : 0;
                $boxNumber = $row[8] ? trim($row[8])   : 0;
                $boxNLength = $row[9] ? trim($row[9])  : 0;
                $boxNWidth = $row[10] ? trim($row[10]) : 0;
                $boxHeight = $row[11] ? trim($row[11]) : 0;
                $account = $row[12] ? trim($row[12]) : '';
                $overseas = $row[13] ? trim($row[13]) : '';
                $channel = $row[14] ? trim($row[14]) : '';
                $remark = $row[15] ? trim($row[15])  : '';

                if (count($row) <= 15) {
                    $errors[$count] = '模板格式异常，请查看模板是否符合上传要求！';
                    continue;
                }

                $country = strtoupper($_country);
                $countryId = SysCountry::getIdByCountry($country);
                if(!$countryId){
                    $errors[$count] = $_country.'系统不存在该国家';
                    continue;
                }

                $key = $country.'-'.$platSku;
                if(!in_array($key, $arr)){
                    $arr[$count] = $key;
                }else{
                    $errors[$count] = '重复记录';
                    continue;
                }

                $productSku = ProductSku::getModelByCode($sku);
                if(!$productSku){
                    $errors[$count] = $sku.'系统不存在该公司sku';
                    continue;
                }
                $strPskuCn  = formatTrim(' ', '', $productSku->psku_cn); //去除产品sku中的所有空格
                $strSkuName = formatTrim(' ', '', $skuName); //去除excel产品中的所有空格
                if($strPskuCn != $strSkuName){
                    $errors[$count] = $key.',对应产品名称不匹配 (请核对产品名称是否正确？)';
                    continue;
                }

                //亚马逊平台
                if ($platId == SysPlat::PLAT_AMAZON) {
                    if ($isFnsku == 1) { //贴标
                        if(!$asin){
                            $errors[$count] = ',贴标状态下，asin必填';
                            continue;
                        }
                    }
                    if(!$_country || !$sku || !$platSku || !$skuName){
                        $errors[$count] = ',必填项不能为空';
                        continue;
                    }
                    $amazonSku = ProductAmazonSku::query()
                        ->where('country_id', $countryId)
                        ->where('seller_sku', $platSku)
                        ->first();
                    if(!$amazonSku){
                        $errors[$count] = $key.',系统未匹配到该国家下的亚马逊平台SKU';
                        continue;
                    }
                    if($amazonSku->psku_id != $productSku->id){
                        $errors[$count] = $key.',对应产品SKU不匹配 (请核对产品SKU是否正确？)';
                        continue;
                    }
                    if ($amazonSku->account->aws_region == 'EU') { //EU，验证产品型号字段
                        if ($productSku->classify->model_no != $skuModelNo) {
                            $errors[$count] = $key.',对应产品SKU产品型号不匹配 (请核对产品SKU产品型号标是否正确？)';
                            continue;
                        }
                    }
                    if($amazonSku->child_asin != $asin){
                        $errors[$count] = $key.',对应ASIN不匹配 (请核对ASIN是否正确？)';
                        continue;
                    }
                }

                //独立站平台
                if ($platId == SysPlat::PLAT_SHOPIFY) {
                    $errors[$count] = '功能暂停！(如需启用，请联系IT！)';
                    continue;
                }

                //乐天平台
                if ($platId == SysPlat::PLAT_RAKUTEN) {
                    if(!$_country || !$sku || !$platSku){
                        $errors[$count] = ',必填项不能为空';
                        continue;
                    }
                    $rakutenSku = ProductRakutenSku::query()
                        ->where('country_id', $countryId)
                        ->where('seller_sku', $platSku)
                        ->first();
                    if(!$rakutenSku){
                        $errors[$count] = $key.',系统未匹配到该国家下的乐天平台SKU';
                        continue;
                    }
                    if($rakutenSku->psku_id != $productSku->id){
                        $errors[$count] = $key.',对应产品SKU不匹配 (请核对产品SKU是否正确？)';
                        continue;
                    }
                }

                /******** 验证库存(参数) ************/
                $areaId = SysCountry::getAreaIdByCountryId($countryId);
                if(!$areaId){
                    $errors[$count] = $_country.',系统不存在该站点';
                    continue;
                }
                $items[$key] = [
                    'plat_id' => $platId,
                    'area_id' => $areaId,
                    'psku_id' => $productSku->id,
                    'apply_num' => $number,
                ];
                /********* 验证库存(参数) ***********/
            }

            if(empty($items)){
                $errors[] = '本次上传文件未能导入系统：无符合条件的数据';
            }

            /********* 验证库存 start***********/
            $applyTotalArr = getArrayValueSum($items); //sku汇总数量
            $inventoryErrors = [];
            foreach ($items as $_key => $_detail){
                $inventory = InventoryCn::query()
                    ->where('area_id',$_detail['area_id'])
                    ->where('psku_id',$_detail['psku_id'])
                    ->first();
                if (!$inventory) {
                    $inventoryErrors[$_key] = '无站点库存';
                    continue;
                }
                //验证：库存总量是否满足
                $skuApplyTotal = $applyTotalArr[$_detail['psku_id']]; //同一sku的累计总量
                if ($inventory->instant < $skuApplyTotal) {
                    $inventoryErrors[$_key] = '站点库存总量小于发货总数量，当前库存:'.$inventory->instant.',SKU总申发数量为:'.$skuApplyTotal;
                }
                //验证：库存是否满足
                if ($inventory->instant < $_detail['apply_num']) {
                    $inventoryErrors[$_key] = '站点库存不足，差额：'.($_detail['apply_num'] - $inventory->instant);
                    continue;
                }
            }
            if(!empty($inventoryErrors)){
                return RExcel::importResult($inventoryErrors);
            }
            /********* 验证库存 end***********/

            if(empty($errors)){
                DB::beginTransaction();
                //创建信息
                $reviewObj = DeliveryReview::query()
                    ->create([
                        'plat_id'   => $platId, //平台
                        'type'      => $type,
                        'file_name' => $fileName,
                        'is_fnsku'  => $isFnsku, //是否贴标
                        'seller_id' => Admin::user()->id
                    ]);
                if($reviewObj){
                    //上传文件
                    $fileDir = DeliveryReview::fileDir($type, strtotime($reviewObj->created_at));
                    $uploadFile = UploadFile::getInit();
                    $uploadFile->upload($file, $fileDir);
                    DB::commit();
                }else{
                    DB::rollBack();
                }
                return ['flag' => true,'data' => $fileName];
            }else{
                return RExcel::importResult($errors);
            }
        }catch(\Exception $e){
            DB::rollBack();
            report($e);
            return ['flag' => false,'data' => '系统异常！'];
        }
    }

    public function template(Request $request){
        $temp = $request->get('temp');
        $suffix = $request->get('suffix','xlsx');
        return Storage::disk('admin')->download("template/{$temp}-template.{$suffix}");
    }
}
